const std = @import("std");

// 声明Lua C API函数
extern "c" fn luaL_newstate() ?*anyopaque;
extern "c" fn luaL_openlibs(L: ?*anyopaque) void;
extern "c" fn luaL_loadstring(L: ?*anyopaque, s: [*c]const u8) c_int;
// lua_pcall 是宏，需要替换成 lua_pcallk
extern "c" fn lua_pcallk(L: ?*anyopaque, nargs: c_int, nresults: c_int, errfunc: c_int, ctx: usize, k: ?*anyopaque) c_int;
extern "c" fn lua_tolstring(L: ?*anyopaque, idx: c_int, len: [*c]usize) [*c]const u8;
extern "c" fn lua_settop(L: ?*anyopaque, idx: c_int) void;
extern "c" fn lua_close(L: ?*anyopaque) void;

// 在Zig中实现lua_pcall宏
fn lua_pcall(L: ?*anyopaque, nargs: c_int, nresults: c_int, errfunc: c_int) c_int {
    return lua_pcallk(L, nargs, nresults, errfunc, 0, null);
}

// 辅助函数来检查Lua调用结果
fn checkLua(L: ?*anyopaque, result: c_int) !void {
    if (result != 0) {
        const err_msg = lua_tolstring(L, -1, null);
        if (err_msg != null) {
            std.debug.print("Lua error: {s}\n", .{err_msg});
        }
        lua_settop(L, -2); // 从栈中移除错误消息
        return error.LuaError;
    }
}

pub fn main() !void {
    std.debug.print("Starting Zig Lua example...\n", .{});

    // 创建Lua状态机
    const L = luaL_newstate();
    if (L == null) {
        std.debug.print("Failed to create Lua state\n", .{});
        return error.LuaInitFailed;
    }

    // 打开标准库
    luaL_openlibs(L);

    // 示例1: 执行简单的Lua代码
    std.debug.print("\n1. Executing simple Lua code:\n", .{});
    const lua_code =
        \\local x = 10
        \\local y = 20
        \\local sum = x + y
        \\print('Sum from Lua:', sum)
        \\return sum
    ;

    try checkLua(L, luaL_loadstring(L, lua_code));
    try checkLua(L, lua_pcall(L, 0, 1, 0));

    // 获取返回值
    const result = lua_tolstring(L, -1, null);
    std.debug.print("Lua returned: {s}\n", .{result});
    lua_settop(L, -2); // 清理栈

    // 示例2: 调用Lua数学函数
    std.debug.print("\n2. Calling Lua math functions:\n", .{});
    const math_code =
        \\function add(a, b)
        \\  return a + b;
        \\end
        \\function multiply(a, b)
        \\  return a * b;
        \\end
        \\return { add = add, multiply = multiply }
    ;
    try checkLua(L, luaL_loadstring(L, math_code));
    try checkLua(L, lua_pcall(L, 0, 1, 0));

    // 现在栈顶有一个table，包含add和multiply函数
    // 在实际应用中，我们会使用lua_getfield等函数来调用这些函数
    std.debug.print("Lua math functions loaded successfully\n", .{});
    lua_settop(L, -2); // 清理栈

    // 示例3: 使用Lua的字符串处理
    std.debug.print("\n3. String manipulation in Lua:\n", .{});
    const string_code =
        \\local name = 'Zig Programmer'
        \\local reversed = name:reverse()
        \\local upper = name:upper()
        \\return reversed .. ' | ' .. upper
    ;
    try checkLua(L, luaL_loadstring(L, string_code));
    try checkLua(L, lua_pcall(L, 0, 1, 0));

    const string_result = lua_tolstring(L, -1, null);
    std.debug.print("String result: {s}\n", .{string_result});
    lua_settop(L, -2); // 清理栈

    // 关闭Lua状态机
    lua_close(L);
    std.debug.print("\nLua example completed successfully!\n", .{});
}
